"""
Django ViewSet filterset_fields 关联字段查询示例
展示不同的关联字段查询方式
"""

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.filters import SearchFilter, OrderingFilter
from django.contrib.auth.models import Group, Permission, User
import django_filters


# ============================================================================
# 示例1：简单列表格式 - 直接使用关联字段路径
# ============================================================================
class GroupViewSetExample1(viewsets.ModelViewSet):
    """使用列表格式的关联字段查询"""
    queryset = Group.objects.all()
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    
    # ViewSet标准列表格式 - 直接支持关联字段
    filterset_fields = [
        'name',                                    # 直接字段
        'permissions__codename',                   # 一级关联：权限代码名
        'permissions__name',                       # 一级关联：权限名称
        'permissions__content_type__app_label',    # 二级关联：应用标签
        'permissions__content_type__model',        # 二级关联：模型名
        'permissions__content_type_id',            # 关联ID
    ]
    
    # URL使用示例：
    # GET /api/groups/?name=admin
    # GET /api/groups/?permissions__codename=add_user
    # GET /api/groups/?permissions__content_type__app_label=auth
    # GET /api/groups/?permissions__content_type__model=user


# ============================================================================
# 示例2：字典格式 - 支持多种查询类型
# ============================================================================
class GroupViewSetExample2(viewsets.ModelViewSet):
    """使用字典格式的关联字段查询"""
    queryset = Group.objects.all()
    filter_backends = [DjangoFilterBackend]
    
    # ViewSet标准字典格式 - 支持多种查询类型
    filterset_fields = {
        'name': ['exact', 'icontains'],                              # 组名：精确匹配 + 包含匹配
        'permissions__codename': ['exact', 'icontains'],             # 权限代码：精确 + 包含
        'permissions__name': ['exact', 'icontains'],                 # 权限名称：精确 + 包含
        'permissions__content_type__app_label': ['exact'],           # 应用标签：精确匹配
        'permissions__content_type__model': ['exact', 'in'],         # 模型名：精确 + 多选
        'permissions__content_type_id': ['exact', 'in'],             # 内容类型ID：精确 + 多选
    }
    
    # URL使用示例：
    # GET /api/groups/?name=admin                                    # 精确匹配
    # GET /api/groups/?name__icontains=admin                         # 包含匹配
    # GET /api/groups/?permissions__codename__icontains=user         # 权限代码包含
    # GET /api/groups/?permissions__content_type__model__in=user,group  # 多模型选择
    # GET /api/groups/?permissions__content_type_id__in=1,2,3        # 多ID选择


# ============================================================================
# 示例3：自定义FilterSet - 最灵活的方式
# ============================================================================
class GroupFilterSet(django_filters.FilterSet):
    """自定义FilterSet - 提供用户友好的参数名"""
    
    # 自定义参数名，映射到关联字段
    app_label = django_filters.CharFilter(
        field_name='permissions__content_type__app_label',
        lookup_expr='exact',
        help_text='按应用标签过滤'
    )
    
    model_name = django_filters.CharFilter(
        field_name='permissions__content_type__model',
        lookup_expr='exact',
        help_text='按模型名过滤'
    )
    
    permission_code = django_filters.CharFilter(
        field_name='permissions__codename',
        lookup_expr='icontains',
        help_text='按权限代码过滤（包含匹配）'
    )
    
    content_type_ids = django_filters.BaseInFilter(
        field_name='permissions__content_type_id',
        help_text='按内容类型ID列表过滤'
    )
    
    # 还可以使用标准字段
    class Meta:
        model = Group
        fields = {
            'name': ['exact', 'icontains'],
            'permissions__name': ['exact', 'icontains'],
        }

class GroupViewSetExample3(viewsets.ModelViewSet):
    """使用自定义FilterSet的关联字段查询"""
    queryset = Group.objects.all()
    filter_backends = [DjangoFilterBackend]
    filterset_class = GroupFilterSet  # 使用自定义FilterSet
    
    # URL使用示例：
    # GET /api/groups/?app_label=auth                    # 自定义参数名
    # GET /api/groups/?model_name=user                   # 自定义参数名
    # GET /api/groups/?permission_code=user              # 自定义参数名
    # GET /api/groups/?content_type_ids=1,2,3            # 自定义参数名
    # GET /api/groups/?name__icontains=admin             # 标准字段
    # GET /api/groups/?permissions__name=Can add user    # 标准关联字段


# ============================================================================
# 示例4：用户ViewSet - 反向关联查询
# ============================================================================
class UserViewSetExample(viewsets.ModelViewSet):
    """用户ViewSet - 展示反向关联查询"""
    queryset = User.objects.all()
    filter_backends = [DjangoFilterBackend]
    
    filterset_fields = {
        'username': ['exact', 'icontains'],
        'email': ['exact', 'icontains'],
        'is_active': ['exact'],
        'is_staff': ['exact'],
        
        # 反向关联：通过组查询用户
        'groups__name': ['exact', 'icontains'],                     # 按组名查询用户
        'groups__permissions__codename': ['exact', 'icontains'],    # 按组权限查询用户
        'groups__permissions__content_type__app_label': ['exact'],  # 按组权限应用查询用户
        
        # 直接权限关联
        'user_permissions__codename': ['exact', 'icontains'],       # 按用户直接权限查询
        'user_permissions__content_type__app_label': ['exact'],     # 按用户权限应用查询
    }
    
    # URL使用示例：
    # GET /api/users/?groups__name=admin                           # 属于admin组的用户
    # GET /api/users/?groups__permissions__codename=add_user       # 有add_user权限的用户
    # GET /api/users/?groups__permissions__content_type__app_label=auth  # 有auth应用权限的用户


# ============================================================================
# 总结：ViewSet关联字段查询的三种方式
# ============================================================================

"""
1. 列表格式（最简单）：
   filterset_fields = ['field', 'related__field', 'related__nested__field']
   
2. 字典格式（支持多种查询类型）：
   filterset_fields = {
       'field': ['exact', 'icontains'],
       'related__field': ['exact', 'in'],
   }
   
3. 自定义FilterSet（最灵活）：
   class CustomFilterSet(django_filters.FilterSet):
       custom_param = django_filters.CharFilter(field_name='related__field')
   
   filterset_class = CustomFilterSet

关联字段语法：
- 一级关联：model__field
- 多级关联：model__related__field
- 反向关联：related_name__field
- ID关联：related_id 或 related__id

查询类型：
- exact: 精确匹配
- icontains: 包含匹配（忽略大小写）
- in: 多值匹配
- gte/lte: 大于等于/小于等于
- isnull: 是否为空
"""
